package ConfigVOMaker

import (
	"gitee.com/fierce_wolf/go-fox-edge-common/commEntity"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Json"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Map"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Method"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/NULL"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Slice"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/String"
	"gitee.com/fierce_wolf/go-fox-edge-common/edgeEntity"
	"reflect"
	"strings"
)

func PreProcess(entity *edgeEntity.ConfigEntity, exist *edgeEntity.ConfigEntity) {
	process(entity, exist)
}

func process(entity *edgeEntity.ConfigEntity, exist *edgeEntity.ConfigEntity) {
	configParam := entity.ConfigParam
	configValue := entity.ConfigValue
	if Method.HasEmpty(configParam, configValue) {
		return
	}

	// 取出配置項
	list := configParam["list"]
	if Method.HasEmpty(list) {
		return
	}
	paramList := list.([]interface{})

	for _, param := range paramList {
		value := NULL.Type(make(map[string]interface{}))
		if exist != nil {
			value = exist.ConfigValue
		}

		processParam(param.(map[string]interface{}), configValue, value)
	}

}

func processParam(param map[string]interface{}, configValue map[string]interface{}, existValue map[string]interface{}) {
	// 提取业务参数
	fieldName := Map.GetString(param, "fieldName", "")
	valueType := Map.GetString(param, "valueType", "")
	defaultValue := Map.GetString(param, "defaultValue", "")
	showMode := Map.GetString(param, "showMode", "")

	// 转换成为数组参数
	fields := strings.Split(fieldName, ".")

	// 取出输入的新数值
	args := Slice.Interfaces(fields)
	newValue, err := Map.GetValue(configValue, args...)
	if err != nil || newValue == nil {
		newValue = defaultValue
	}

	// 取出已经存在的旧数值
	oldValue := NULL.Interface()
	if existValue != nil {
		args = Slice.Interfaces(fields)
		oldValue, err = Map.GetValue(existValue, args...)
		if err != nil || oldValue == nil {
			oldValue = defaultValue
		}
	}

	// 至少包含fieldName和valueType字段
	if Method.HasEmpty(newValue) {
		return
	}

	// 验证数值的类型是否正确
	if !verifyValueType(valueType, newValue) {
		return
	}

	// 下面是各种具体行为

	// 隐藏信息用的覆盖字符串
	hideString := "****"

	if existValue == nil {
		// 后期处理

		// 场景1：密码的安全显示
		if "Security" == showMode {
			args = Slice.Interfaces(fields)
			args = append(args, hideString)
			Map.SetValue(configValue, args...)
		}
	} else {
		// 前期处理

		// 场景1：密码的原文存储：如果新的数据是"****"，说明用户并没有修改
		if ("Security" == showMode) && hideString == newValue {
			realValue := ""
			if oldValue != nil {
				realValue = String.ToString(oldValue)
			}
			// 将真实的数据，更新到用户的输入数据之中
			args = Slice.Interfaces(fields)
			args = append(args, realValue)
			Map.SetValue(configValue, args...)
		}
	}
}

func verifyValueType(valueType string, value interface{}) bool {
	if valueType == "string" {
		return reflect.TypeOf(value).Kind() == reflect.String
	}

	return false
}

func PostProcess(entityList []commEntity.IEntity) []commEntity.IEntity {
	result := make([]commEntity.IEntity, 0)

	for _, entity := range entityList {
		// 利用JSON转换的过程，深度clone一个副本，避免接下来的修改操作影响到源数据
		clone := edgeEntity.Type.ConfigEntity.Instance()
		err := Json.Clone(entity, clone)
		if err != nil {
			continue
		}

		postProcess(clone)

		result = append(result, clone)
	}

	return result
}

func postProcess(entity *edgeEntity.ConfigEntity) {
	process(entity, nil)
}
